package org.ruoyi.ppt.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.ppt.domain.PptResult;
import org.ruoyi.ppt.domain.PptWithImages;
import org.ruoyi.ppt.domain.vo.PptStatusVo;
import org.ruoyi.ppt.mapper.PptResultMapper;
import org.ruoyi.ppt.service.PptService;
import org.ruoyi.ppt.utils.CacheKeyUtil;
import org.ruoyi.system.domain.vo.SysOssVo;
import org.ruoyi.system.service.ISysOssService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.util.*;
import static org.ruoyi.ppt.service.PptService.containsKeyword;

/**
 *课件生成
 *
 * @author anran
 * @date 2025/9/17/周三 14:03
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/ppt")
public class PptController extends BaseController {

    private final PptService pptService;

    private final ISysOssService ossService;

    private final RedisTemplate<String, String> redisTemplate;

    private final PptResultMapper pptResultMapper;

    /**
     *
     * 通过消息内容返回调用哪个接口
     * * @param text 参数
     */
    @GetMapping("/getStatusByText")
    public R<Map<Object, Object>> getStatusByText(@RequestParam(name = "text") String text) {
        List<String> keywords = Arrays.asList("生成", "PPT", "ppt");
        boolean hasKeyword = containsKeyword(text, keywords);
        Map<Object, Object> statusMap = new HashMap<>();
        if (hasKeyword) {
            statusMap.put("statusId", 1);
        }else {
            statusMap.put("statusId", 0);
        }
        return R.ok(statusMap);
    }

    /**
     * 一句话描述（主题）生成ppt
     *
     * @param requestBody 参数
     */

    @PostMapping("/ppt-create")
    public R<Object> getPptCreate(@RequestBody String requestBody) {
        return R.ok(pptService.getPptCreate(requestBody));
    }

    /**
     * 获取生成PPT结果
     *
     * @param id 任务ID
     */

    @GetMapping("/ppt-result")
    public R<Object> getPptResult(@RequestParam(name = "id") String id) {
        String key = CacheKeyUtil.PPT_STATUS + id;
        String cache = redisTemplate.opsForValue().get(key);
        if (cache != null)
            return R.ok(JSON.parseObject(cache, PptStatusVo.class));

        PptResult p = pptResultMapper.selectById(id);
        if (p != null && p.getStatus() == 2) {
            PptStatusVo vo = new PptStatusVo(id, 2,100,p.getPreviewUrl(), "完成");
            redisTemplate.opsForValue().set(key, JSON.toJSONString(vo), Duration.ofMinutes(10));
            return R.ok(vo);
        }
        String lockKey = CacheKeyUtil.PPT_TASK_LOCK + id;
        Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey,"1",Duration.ofSeconds(3));
        if (Boolean.TRUE.equals(locked)) {
            try {
                pptService.pullAndSave(id);
            } finally {
                redisTemplate.delete(lockKey);
            }
        }
        return R.ok(PptStatusVo.processing());
//        return R.ok(pptService.getPptResult(id));
    }

    /**
     * 获取PPT编辑器
     *
     * @param requestBody 参数
     */

    @PostMapping("/ppt-editor")
    public R<Object> getPptEditor(@RequestBody String requestBody) {
        return R.ok(pptService.getPptEditor(requestBody));
    }

    /**
     * 生成大纲
     *
     * @param requestBody 参数
     */

    @PostMapping("/ppt-structure")
    public R<Object> getPptStructure(@RequestBody String requestBody) {
        return R.ok(pptService.getPptStructure(requestBody));
    }

    /**
     * AI模板生成方案
     *
     * @param requestBody 参数
     */

    @PostMapping("/ppt-cover")
    public R<Object> getPptCover(@RequestBody String requestBody) {
        return R.ok(pptService.getPptCover(requestBody));
    }

    /**
     * ppt下载
     *
     * @param id 任务ID
     */

    @GetMapping("/ppt-download")
    public R<Object> getPptDownload(@RequestParam(name = "id") String id) {
        return R.ok(pptService.getPptDownload(id));
    }


    /**
     * 自定义大纲生成ppt
     *
     * @param requestBody 自定义大纲参数
     */

    @PostMapping("/ppt-structure-custom")
    public R<Object> getPptStructureCustom(@RequestBody String requestBody) {
        return R.ok(pptService.getPptStructureCustom(requestBody));
    }

    /**
     * 基于文件生成ppt
     *
     * @param file 文件
     * @param name 作者
     */

    @PostMapping(value = "/ppt-create-file",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Object> getPptCreateFile(@RequestPart("file") MultipartFile file,@RequestParam(name = "name") String name) {
        if (ObjectUtil.isNull(file)) {
            return R.fail("上传文件不能为空");
        }
        return R.ok(pptService.getPptCreateFile(file,name));
    }

    /**
     * MarkDown大纲生成PPT
     *
     * @param requestBody MarkDown大纲参数
     */

    @PostMapping("/ppt-structure-markdown")
    public R<Object> getPptStructureMarkdown(@RequestBody String requestBody) {
        return R.ok(pptService.getPptStructureMarkdown(requestBody));
    }

    /**
     * 通过id获取ppt图片
     *
     * @param id
     */
    @GetMapping("/ppt-images")
    public R<PptWithImages> getPptImages(@RequestParam (name = "id") String id) {
         return R.ok(pptService.getPptImages(id));
    }

    /**
     * ppt结果List
     *
     *
     */
    @GetMapping("/ppt-List")
    public R<List<PptResult>>getPptList() {
        return R.ok(pptService.getPptList());
    }

    /**
     * 测试
     *
     * @param files 文件
     */

    @PostMapping(value = "/test", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public List<String> getTest(@RequestPart("file") MultipartFile[] files) {
        if (ObjectUtil.isEmpty(files)) {
            throw new ServiceException("上传文件不能为空");
        }

        List<String> urls = new ArrayList<>();
        for (MultipartFile file : files) {
            if (file.isEmpty()) continue;
            SysOssVo upload = ossService.upload(file);
            urls.add(upload.getUrl());
        }

        return urls;
    }


}
